############## 属性和方法的判断
'''
因为python的对象可以动态的添加属性，并且多态那里还讲到了鸭子类型，
所以就需要有个方法来判断指定对象是否支持某个属性或者方法
'''
class Animal(object):

    def __init__(self):
        self.x = 9;

    def run(self):
        print('Animal is running...')


class Dog(Animal):
    pass;

class Cat(Animal):
    def run(self):
        print('Cat is running...');


dog = Dog();
dog2 = Dog();
cat = Cat();

print('#=========hasattr函数：判断对象是否含有某方法或属性=============');
if hasattr(dog, 'x'):
    print('dog has 属性x')

if hasattr(dog, 'run'):
    print('dog有run方法')

print('#=========动态绑定属性和方法=============');
cat.name = 'Michael'
print(cat.name)

#给实例绑定一个方法
def set_age(self, age): # 定义一个函数作为实例方法
    self.age = age
from types import MethodType
cat.set_age = MethodType(set_age, cat)
cat.set_age(25)
print(cat.age)

#给类绑定一个方法
Animal.set_age = MethodType(set_age, Animal)

print('#=========限制动态绑定属性和方法，使用__slots__=============');
class A(object):
    #限定只能有指定属性，只对当前类起作用，不通过继承传递
    __slots__ = ('name', 'age')  # 用tuple定义允许绑定的属性名称

s = A()
s.name = 'michael'
s.age = 23
#s.score = 323  #会报错

print('#=========@property：用访问属性的方式访问getter和setter=============');
class B(object):

    #定义属性：s = b.score
    @property
    def score(self):
        return self._score

    #定义属性：b.score = 44
    @score.setter
    def score(self, value):
        self._score = value

b = B();
b.score = 44;
print(b.score);












#
